import os
import logging
import argparse
import platform
from query import Query
from dot import ImageDot
import sys

class Main:
    def __init__(self, entry_point_packages, conf, arch, weak, package_in_image, remove_test):
        self.depends_dict = {}
        self.entry_point_package = entry_point_packages
        self.conf = conf
        self.arch = arch
        self.weak = weak
        self.package_in_image = package_in_image
        self.remove_test = remove_test

        self.q = Query(conf, arch, package_in_image)
        self.q.load_repo_data()

    def recur_add(self, pkg):
        if self.remove_test != None and pkg in self.remove_test:
            return

        req_set = self.q.query_depends(pkg,'require')
        if self.weak:
            rec_set = self.q.query_depends(pkg,'recommends') 
            all_set = set.union(req_set, rec_set)
        else:
            all_set = req_set
        self.depends_dict[pkg] = all_set

        for dep_pkg in all_set:
            if self.remove_test != None and dep_pkg in self.remove_test:
                continue
            if dep_pkg not in self.depends_dict:
                self.recur_add(dep_pkg)
    
    def run(self):
        for pkg in self.entry_point_package:
            self.recur_add(pkg)

    def get_depends_dict(self):
        for k, v in self.depends_dict.items():
            print(k, v)
    
    def get_required_list(self):
        for k, _ in self.depends_dict.items():
            print(k)

    def get_output_file(self, colored, all_dict):
        img_dot = ImageDot()
        img_dot.generate_dot(self.depends_dict, colored, all_dict)
        img_dot.save()
    
    def get_entry_point(self):
        for r in self.package_in_image:
            father = self.q.query_what_depends(r,"require")
            if len(father) == 0:
                print(r)

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)

def init_args():

    parser = MyParser(description="image dependency list tool")
    parser.add_argument('source', help='source repository configuration file')
    parser.add_argument('-w','--weak_dependency_enabled', action='store_true', help='enable weak dependency check')
    parser.add_argument('-arch','--architecture', nargs='?', default=platform.machine(), help='image architecture default is platform.machine()')
    parser.add_argument('-e','--entry_point_package', nargs='?', help='show entry point package of an image')
    parser.add_argument('-v', '--verbose', action='store_true', help='show verbose log')
    parser.add_argument('-p','--package', nargs='+', help='pakcage to analyse')
    parser.add_argument('-sd', '--show_dependency_dict', action='store_true', help='show dependency dict (default show package list)')
    parser.add_argument('-g', '--generate_dot_and_png', action='store_true', help='generate dependency dot and png file')
    parser.add_argument('-rt', '--remove-test', nargs='+', help='remove test for current dependency dot')
    parser.add_argument('-colored', '--colored_remove_test', action='store_true', help='generate dependency dot and png file of colored packages in remove-test')

    return parser

def main():
    parser = init_args()
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.ERROR)

    packages_in_image = []
    if args.entry_point_package:
        f = open(args.entry_point_package,'r')
        packages_in_image = f.read().splitlines()

    m = Main(args.package, args.source, args.architecture, args.weak_dependency_enabled, packages_in_image, args.remove_test)

    if args.entry_point_package:
        m.get_entry_point()
        return
    if args.package == None:
        print("please input packages to parse")
        return
        
    m.run()

    if args.show_dependency_dict:
        m.get_depends_dict()
    else:
        m.get_required_list()

    if args.colored_remove_test:
        m_all = Main(args.package, args.source, args.architecture, args.weak_dependency_enabled, packages_in_image, [])
        m_all.run()
        m.get_output_file(True,m_all.depends_dict)


    if not args.colored_remove_test and args.generate_dot_and_png:
        m.get_output_file(False,{})

main()